package cn.bmyi.apiautotest.common;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;

/**
 * 基于JDBC实现数据库操作
 * 
 * @author 毛建杰
 *
 */
public class SQLConnection
{
	private static Connection connection = null;
	private static PreparedStatement statement = null;
	private static ResultSet resultSet = null;

	/**
	 * 新建数据库连接
	 * 
	 * @param jdbcDriver
	 *            JDBC驱动程序类名
	 * @param url
	 *            提供JDBC连接的URL。 URL定义了连接数据库时的协议、子协议、数据源标识。 书写形式：协议:子协议:数据源标识；
	 *            协议：在JDBC中总是以jdbc开始； 子协议：是桥连接的驱动程序或是数据库管理系统名称；
	 *            数据源标识：标记找到数据库来源的地址与连接端口。
	 * 
	 *            例如：
	 *            SqlServer："jdbc:sqlserver://172.3.207.27:1433;DatabaseName=bmy"
	 *            MySQL："jdbc:mysql://172.3.207.13:3306/zentao"
	 * @param user
	 *            数据库的用户名
	 * @param password
	 *            数据库的密码
	 */
	public static void connect(String jdbcDriver, String url, String user, String password)
	{
		try
		{
			// 加载jdbc驱动
			Class.forName(jdbcDriver);
			// 创建数据库连接
			connection = DriverManager.getConnection(url, user, password);
			Logger.info("连接数据库成功：" + url);
		}
		catch (ClassNotFoundException e)
		{
			Logger.error("找不到jdbc驱动程序类，加载驱动失败！");
			Logger.error(e.getMessage());
			close();
		}
		catch (SQLException e)
		{
			Logger.error("数据库连接失败！");
			Logger.error(e.getMessage());
			close();
		}
	}

	/**
	 * 执行查询数据库的SQL语句。 执行结束后关闭数据库连接。
	 * 
	 * @param sql
	 *            SQL语句
	 * @return 查询结果；如果无结果或者报错，返回null
	 */
	public static String[][] executeQuery(String sql)
	{
		// 执行sql语句，查询结果保存到resultSet
		if (connection != null)
		{
			try
			{
				statement = connection.prepareStatement(sql);
				resultSet = statement.executeQuery();
				Logger.info("执行sql成功：" + sql);
			}
			catch (SQLException e)
			{
				Logger.error(e.getMessage());
				close();
				return null;
			}
		}

		// 获取resultSet列数
		int columnCount;
		try
		{
			columnCount = resultSet.getMetaData().getColumnCount();
		}
		catch (SQLException e)
		{
			Logger.error(e.getMessage());
			close();
			return null;
		}

		// resultSet转换为ArrayList<String[]>
		ArrayList<String[]> arrayList = new ArrayList<String[]>();
		try
		{
			while (resultSet.next())
			{
				String[] row = new String[columnCount];
				for (int i = 0; i < columnCount; i++)
				{
					row[i] = resultSet.getString(i + 1);
				}
				arrayList.add(row);
			}
		}
		catch (SQLException e)
		{
			Logger.error(e.getMessage());
			return null;
		}
		finally
		{
			close();
		}

		// ArrayList<String[]>转换为String[][]，关闭JDBC对象，返回String[][]
		String[][] ret = (String[][]) arrayList.toArray(new String[0][0]);
		return ret;
	}

	/**
	 * 执行INSERT、UPDATE、DELETE语句以及DDL语句。 执行结束后关闭数据库连接。
	 * 
	 * @param sql
	 *            SQL语句
	 * @return 本次操作影响到的记录数
	 */
	public static int executeUpdate(String sql)
	{
		if (connection != null)
		{
			try
			{
				statement = connection.prepareStatement(sql);
				int ret = statement.executeUpdate();
				Logger.info("执行sql成功：" + sql);
				return ret;
			}
			catch (SQLException e)
			{
				Logger.error(e.getMessage());
				return -1;
			}
			finally
			{
				close();
			}
		}
		close();
		return -1;
	}

	/**
	 * 释放JDBC资源
	 */
	private static void close()
	{
		// 释放resultSet
		if (resultSet != null)
		{
			try
			{
				resultSet.close();
			}
			catch (SQLException e)
			{
				Logger.error(e.getMessage());
			}
		}

		// 释放statement
		if (statement != null)
		{
			try
			{
				statement.close();
			}
			catch (SQLException e)
			{
				Logger.error(e.getMessage());
			}
		}

		// 释放connection
		if (connection != null)
		{
			try
			{
				connection.close();
			}
			catch (SQLException e)
			{
				Logger.error(e.getMessage());
			}
		}
	}
}
